package branch.snapshot;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import branch.Branch;
import branch.BranchDAO;

public class BranchRecord implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -8612286924814635501L;
	
	List<ChannelRecord> channelRecords;
	private final Set<Integer> participatingBranchIds;
	private final int branchId;
	private final int initialAmount; // currentAmount of branch at the beginning of the record phase
	Marker marker;
	
	public BranchRecord(int initialAmount, Set<Integer> participatingBranchIds, int branchId, Marker marker) {
		this.initialAmount = initialAmount;
		this.channelRecords = new ArrayList<ChannelRecord>();
		this.participatingBranchIds = participatingBranchIds;
		this.branchId = branchId;
		this.marker = marker;
	}
	
	public void testForCompletion(Branch b){
		if(isBranchRecordComplete())
			b.onBranchRecordCompleted(this);
	}
	
	public void record(ChannelRecord r, Branch b){
		channelRecords.add(r);
		
		testForCompletion(b);
	}
	
	public int getBranchID(){
		return branchId;
	}
	
	public Marker getMarker(){
		return marker;
	}
	
	public int getInitialAmount(){
		return initialAmount;
	}
	
	public List<ChannelRecord> getChannelRecords(){
		return channelRecords;
	}
	
	private Set<Integer> getRecordedChannelDistantBranchId(){
		HashSet<Integer> recordedBranchId = new HashSet<Integer>();
		for (ChannelRecord record : channelRecords){
			recordedBranchId.add(record.getDistantBranchId());
		}
		
		return recordedBranchId;
	}
	
	private boolean isBranchRecordComplete(){
		boolean isComplete = true;
		Set recordedBranchId = getRecordedChannelDistantBranchId();
		for (int participatingBranchId : participatingBranchIds){
			if (participatingBranchId > branchId)
				isComplete = recordedBranchId.contains(participatingBranchId);
			
			if(!isComplete)
				break;
		}
		
		return isComplete;
	}
}
